package com.dmx.cep.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class Download {
	private static Log log = LogFactory.getLog(Download.class);
    public Download()
    {
        m_denyPhysicalPath = false;
        m_contentDisposition = new String();
    }	

    public final void initialize(PageContext pageContext)
        throws ServletException
    {
        m_application = pageContext.getServletContext();
        m_request = (HttpServletRequest)pageContext.getRequest();
        m_response = (HttpServletResponse)pageContext.getResponse();
    }

    private String getFileName(String filePathName)
    {
        String token = new String();
        String value = new String();
        int pos = 0;
        int i = 0;
        int start = 0;
        int end = 0;
        pos = filePathName.lastIndexOf(47);
        if(pos != -1)
            return filePathName.substring(pos + 1, filePathName.length());
        pos = filePathName.lastIndexOf(92);
        if(pos != -1)
            return filePathName.substring(pos + 1, filePathName.length());
        else
            return filePathName;
    }    
    
    public void downloadFile(String sourceFilePathName)
        throws IOException, ServletException
    {
        downloadFile(sourceFilePathName, null, null);
    }    

    public void downloadFile(String sourceFilePathName, String contentType, String destFileName)
        throws IOException, ServletException
    {
        downloadFile(sourceFilePathName, contentType, destFileName, 65000);
    }

    public void downloadFile(String sourceFilePathName, String contentType, String destFileName, int blockSize)
        throws IOException, ServletException
    {
        if(!isVirtual(sourceFilePathName) && m_denyPhysicalPath)
            throw new SecurityException("Physical path is denied (1035).");
        if(isVirtual(sourceFilePathName))
            sourceFilePathName = m_application.getRealPath(sourceFilePathName);
        File file = new File(sourceFilePathName);
        FileInputStream fileIn = new FileInputStream(file);
        long fileLen = file.length();
        int readBytes = 0;
        int totalRead = 0;
        byte b[] = new byte[blockSize];
        if(contentType == null)
            m_response.setContentType("application/x-msdownload");
        else
        if(contentType.length() == 0)
            m_response.setContentType("application/x-msdownload");
        else
            m_response.setContentType(contentType);
        m_response.setContentLength((int)fileLen);
        m_contentDisposition = m_contentDisposition != null ? m_contentDisposition : "attachment;";
        m_response.setHeader("Content-Disposition","attachment; filename="+toUtf8String(getFileName(sourceFilePathName)));
        OutputStream stream = m_response.getOutputStream();
        try {
	        while((long)totalRead < fileLen) 
	        {
	            readBytes = fileIn.read(b, 0, blockSize);
	            totalRead += readBytes;
	            stream.write(b, 0, readBytes);
	        }
        	stream.flush();
        	stream.close();
        }catch(Exception e) {
        	log.error(e.getMessage(),e);
        }finally {
        	fileIn.close();
        }
    }
    

    private boolean isVirtual(String pathName)
    {
        if(m_application.getRealPath(pathName) != null)
        {
            File virtualFile = new File(m_application.getRealPath(pathName));
            return virtualFile.exists();
        }
        else
        {
            return false;
        }
    }

    public static String toUtf8String(String s) {
    	StringBuffer sb = new StringBuffer();
    	for (int i=0;i<s.length();i++) {
    	    char c = s.charAt(i);
    	    if (c >= 0 && c <= 255) {
 				try {
					sb.append(c);
				} catch (Exception e) {
					log.error(e.getMessage(),e);
				}
    	    } else {
    		byte[] b;
    		try {
    		    b = Character.toString(c).getBytes("utf-8");
    		} catch (Exception ex) {
    		    System.out.println(ex);
    		    b = new byte[0];
    		}
    		for (int j = 0; j < b.length; j++) {
    		    int k = b[j];
    		    if (k < 0) k += 256;
    		    sb.append("%" + Integer.toHexString(k).
    		    toUpperCase());
    		}
    	    }
    	}
    	return sb.toString();
    }

    protected HttpServletRequest m_request;
    protected HttpServletResponse m_response;
    protected ServletContext m_application;
    private boolean m_denyPhysicalPath;
    private String m_contentDisposition;
}
